﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using UnityEditor;
using UnityEditor.Utils;
using UnityEngine;

internal class PostProcessAndroidPlayer
{
    internal static string aapt_exe;
    internal static string adb_exe;
    internal static string android_jar;
    internal const string AndroidPlugins = "Assets/Plugins/Android";
    private const string AndroidXmlNamespace = "http://schemas.android.com/apk/res/android";
    internal const int API_LEVEL_GINGERBREAD = 9;
    internal const string consoleMsg = " See the Console for details.";
    internal static string java_exe;
    internal static int platform_api_level;
    internal static ProgressHelper progress = new ProgressHelper();
    private static Dictionary<int, string> s_DeviceProps;
    internal static AndroidSDKTools sdk_tools;
    internal static string zipalign_exe;

    private static Dictionary<int, string> AcquireDeviceInfo(string path_to_adb, string serialno)
    {
        Dictionary<int, string> dictionary = s_DeviceProps;
        int hashCode = "ro.build.serialno".GetHashCode();
        if ((dictionary != null) && serialno.Equals(dictionary[hashCode]))
        {
            return dictionary;
        }
        dictionary = new Dictionary<int, string>();
        string[] strArray = new string[] { "Fetching device information", "Requesting OS configuration data from device " + serialno };
        string args = string.Format("-s {0} shell getprop", serialno);
        string str2 = ExecuteSystemProcess(path_to_adb, args, string.Empty, strArray, progress.Advance());
        char[] separator = new char[] { '\n', '\r' };
        foreach (string str3 in str2.Split(separator))
        {
            string[] strArray3 = new string[] { "]: [" };
            string[] strArray4 = str3.Split(strArray3, StringSplitOptions.None);
            if (strArray4.Length == 2)
            {
                char[] trimChars = new char[] { ' ', '[', ']' };
                string str4 = strArray4[0].Trim(trimChars);
                string str5 = strArray4[1].Trim(trimChars);
                dictionary.Add(str4.GetHashCode(), str5);
            }
        }
        string str6 = string.Format("-s {0} shell cat /proc/meminfo", serialno);
        foreach (string str8 in ExecuteSystemProcess(path_to_adb, str6, string.Empty, strArray, progress.Advance()).Split(separator))
        {
            char[] chArray3 = new char[] { ':', ' ' };
            string[] strArray6 = str8.Split(chArray3, StringSplitOptions.RemoveEmptyEntries);
            if (strArray6.Length >= 2)
            {
                char[] chArray4 = new char[] { ' ', '[', ']' };
                string str9 = strArray6[0].Trim(chArray4);
                string str10 = strArray6[1].Trim(chArray4);
                dictionary.Add(str9.GetHashCode(), str10);
            }
        }
        if (!dictionary.ContainsKey(hashCode))
        {
            dictionary.Add(hashCode, serialno);
        }
        return (s_DeviceProps = dictionary);
    }

    private static void AddUsesFeatureTag(XmlDocument doc, string feature, bool addRequired)
    {
        if (!HasElementWithAttribute(doc, "uses-feature", "android:name", feature))
        {
            XmlElement newChild = CreateNameElem(doc, "uses-feature", feature);
            if (!addRequired)
            {
                newChild.Attributes.Append(CreateAttr(doc, "required", "false"));
            }
            doc.DocumentElement.AppendChild(newChild);
        }
    }

    private static void AlignPackage(string stagingArea)
    {
        string[] strArray = new string[] { "Aligning APK package", "Optimizing target package alignment..." };
        string str = Path.Combine(Environment.CurrentDirectory, stagingArea);
        string args = string.Format("4 \"{0}/Package_unaligned.apk\" \"{0}/Package.apk\"", str);
        string message = ExecuteSystemProcess(zipalign_exe, args, stagingArea, strArray, progress.Advance());
        if ((message.Contains("zipalign") || message.Contains("Warning")) || !File.Exists(Path.Combine(str, "Package.apk")))
        {
            UnityEngine.Debug.LogError(message);
            ShowErrDlgAndThrow("APK Aligning Failed!", "Failed to align APK package. See the Console for details.");
        }
    }

    private static void AppendPermissionWithCheck(XmlDocument doc, XmlElement manifestElem, string attrValue)
    {
        if (!HasElementWithAttribute(doc, "uses-permission", "android:name", attrValue))
        {
            manifestElem.AppendChild(CreateNameElem(doc, "uses-permission", attrValue));
        }
    }

    private static bool ArePasswordsProvided()
    {
        return ((PlayerSettings.Android.keyaliasName.Length == 0) || ((PlayerSettings.Android.keystorePass.Length != 0) && (PlayerSettings.Android.keyaliasPass.Length != 0)));
    }

    private static void BuildApk(string stagingArea, bool sign_using_keystore, bool debuggable)
    {
        string[] strArray = new string[] { "Creating APK package", "Building target package from assets archive and pre-built binaries..." };
        string str = Path.Combine(Environment.CurrentDirectory, stagingArea);
        string[] first = new string[] { "apk", string.Format("{0}/Package_unaligned.apk", str), "-z", string.Format("{0}/assets.ap_", str), "-z", string.Format("{0}/bin/resources.ap_", str), "-nf", string.Format("{0}/libs", str), "-f", string.Format("{0}/bin/classes.dex", str), "-v" };
        if (sign_using_keystore)
        {
            string str2 = !Path.IsPathRooted(PlayerSettings.Android.keystoreName) ? Path.Combine(Directory.GetCurrentDirectory(), PlayerSettings.Android.keystoreName) : PlayerSettings.Android.keystoreName;
            string[] second = new string[] { "-k", str2, "-kp", PlayerSettings.Android.keystorePass, "-kk", PlayerSettings.Android.keyaliasName, "-kkp", PlayerSettings.Android.keyaliasPass };
            first = first.Concat<string>(second).ToArray<string>();
        }
        if (debuggable)
        {
            string[] textArray4 = new string[] { "-d" };
            first = first.Concat<string>(textArray4).ToArray<string>();
        }
        if (File.Exists(Path.Combine(stagingArea, "raw.ap_")) && !PlayerSettings.Android.useAPKExpansionFiles)
        {
            string[] textArray5 = new string[] { "-z", string.Format("{0}/raw.ap_", str) };
            first = first.Concat<string>(textArray5).ToArray<string>();
        }
        string message = SDKTool(first, stagingArea, strArray, progress.Advance());
        string fileName = Path.Combine(stagingArea, "Package_unaligned.apk");
        FileInfo info = new FileInfo(fileName);
        if (!File.Exists(fileName) || (info.Length == 0))
        {
            UnityEngine.Debug.LogError(message);
            ShowErrDlgAndThrow("APK Builder Failed!", "Failed to build APK package. See the Console for details.");
        }
    }

    private static void BuildDex(string playerPackage, string stagingArea)
    {
        FileUtil.CopyFileOrDirectory(playerPackage + "/bin/classes.jar", stagingArea + "/bin/classes.jar");
        string[] strArray = new string[] { "Building DEX", "Converting java.class to dex-format..." };
        string[] command = new string[] { "dx", "--dex", "--verbose", "--output=bin/classes.dex", "bin/classes.jar", "plugins" };
        string str = SDKTool(command, stagingArea, strArray, progress.Advance());
        if (!File.Exists(Path.Combine(stagingArea, "bin/classes.dex")))
        {
            string str2 = Path.Combine(Environment.CurrentDirectory, stagingArea);
            UnityEngine.Debug.LogError("Failed to compile Java code to DEX:\n" + str2 + "> " + string.Join(" ", command) + "\n" + str);
            string message = "Failed to compile Java code to DEX. See the Console for details.";
            ShowErrDlgAndThrow("Building DEX Failed!", message);
        }
    }

    private static void BuildObb(string stagingArea)
    {
        bool flag = File.Exists(Path.Combine(stagingArea, "obb.ap_"));
        bool flag2 = File.Exists(Path.Combine(stagingArea, "raw.ap_"));
        if (flag || flag2)
        {
            string[] strArray = new string[] { "Creating OBB package", "Building APK Expansion package from assets archive..." };
            string str = Path.Combine(Environment.CurrentDirectory, stagingArea);
            string[] first = new string[] { "apk", string.Format("{0}/main.obb", str), "-v", "-d" };
            if (flag)
            {
                string[] second = new string[] { "-z", string.Format("{0}/obb.ap_", str) };
                first = first.Concat<string>(second).ToArray<string>();
            }
            if (flag2)
            {
                string[] textArray4 = new string[] { "-z", string.Format("{0}/raw.ap_", str) };
                first = first.Concat<string>(textArray4).ToArray<string>();
            }
            string message = SDKTool(first, stagingArea, strArray, progress.Advance());
            string fileName = Path.Combine(stagingArea, "main.obb");
            FileInfo info = new FileInfo(fileName);
            if (!File.Exists(fileName) || (info.Length == 0))
            {
                UnityEngine.Debug.LogError(message);
                ShowErrDlgAndThrow("OBB Builder Failed!", "Failed to build OBB package. See the Console for details.");
            }
            if (info.Length >= 0x80000000L)
            {
                UnityEngine.Debug.LogError(message);
                ShowErrDlgAndThrow("OBB Builder Failed!", "OBB file too big for Android Market (max 2GB).\n See the Console for details.");
            }
            PatchStringRes(Path.Combine(stagingArea, "assets/bin/Data/settings.xml"), "bool", GetMD5HashOfEOCD(Path.Combine(stagingArea, "main.obb")), true.ToString());
        }
    }

    private static void ConvertManifestToWallpaper(string manifest)
    {
        XmlDocument doc = new XmlDocument();
        XmlTextReader reader = new XmlTextReader(manifest);
        reader.Read();
        doc.Load(reader);
        reader.Close();
        doc.DocumentElement.SetAttribute("android:installLocation", "internalOnly");
        doc.GetElementsByTagName("uses-sdk")[0].Attributes["android:minSdkVersion"].Value = "7";
        AddUsesFeatureTag(doc, "android.software.live_wallpaper", true);
        IEnumerator enumerator = doc.GetElementsByTagName("activity").GetEnumerator();
        try
        {
            while (enumerator.MoveNext())
            {
                XmlElement current = (XmlElement) enumerator.Current;
                current.ParentNode.RemoveChild(current);
            }
        }
        finally
        {
            IDisposable disposable = enumerator as IDisposable;
            if (disposable == null)
            {
            }
            disposable.Dispose();
        }
        XmlElement element2 = (XmlElement) doc.GetElementsByTagName("application")[0];
        XmlElement newChild = doc.CreateElement("service");
        newChild.Attributes.Append(CreateAttr(doc, "label", "@string/app_name"));
        newChild.Attributes.Append(CreateAttr(doc, "name", "com.unity3d.player.UnityWallpaperService"));
        newChild.Attributes.Append(CreateAttr(doc, "permission", "android.permission.BIND_WALLPAPER"));
        XmlElement element4 = doc.CreateElement("intent-filter");
        XmlElement element5 = doc.CreateElement("action");
        element5.Attributes.Append(CreateAttr(doc, "name", "android.service.wallpaper.WallpaperService"));
        element4.AppendChild(element5);
        newChild.AppendChild(element4);
        XmlElement element6 = doc.CreateElement("meta-data");
        element6.Attributes.Append(CreateAttr(doc, "name", "android.service.wallpaper"));
        element6.Attributes.Append(CreateAttr(doc, "resource", "@xml/wallpaper"));
        newChild.AppendChild(element6);
        element2.AppendChild(newChild);
        doc.Save(manifest);
    }

    internal static void CopyNativeLibs(BuildTarget target, string playerPackage, string stagingArea, string abi, string abi2)
    {
        EnsureLibraryIsAvailable(playerPackage, abi);
        Directory.CreateDirectory(stagingArea + "/libs");
        FileUtil.CopyFileOrDirectory(playerPackage + "/libs/" + abi, stagingArea + "/libs/" + abi);
        PostprocessBuildPlayer.InstallPlugins(stagingArea + "/libs/" + abi, target);
        if (!PostprocessBuildPlayer.InstallPluginsByExtension("Assets/Plugins/Android/libs/" + abi, ".so", stagingArea + "/libs/" + abi, false) && (abi2 != null))
        {
            PostprocessBuildPlayer.InstallPluginsByExtension("Assets/Plugins/Android/libs/" + abi2, ".so", stagingArea + "/libs/" + abi, false);
        }
        if (!File.Exists(stagingArea + "/libs/" + abi + "/gdbserver") && !PostprocessBuildPlayer.InstallPluginsByExtension("Assets/Plugins/Android", "gdbserver", stagingArea + "/libs/" + abi, false))
        {
            PostprocessBuildPlayer.InstallPluginsByExtension("Assets/Plugins/Android/libs/" + abi, "gdbserver", stagingArea + "/libs/" + abi, false);
        }
    }

    private static XmlAttribute CreateAttr(XmlDocument doc, string key, string value)
    {
        XmlAttribute attribute = doc.CreateAttribute("android", key, "http://schemas.android.com/apk/res/android");
        attribute.Value = value;
        return attribute;
    }

    private static XmlElement CreateGlesVersionElem(XmlDocument doc)
    {
        XmlElement element = doc.CreateElement("uses-feature");
        string str = "0x00010001";
        if (PlayerSettings.targetGlesGraphics == TargetGlesGraphics.OpenGLES_2_0)
        {
            str = "0x00020000";
        }
        element.Attributes.Append(CreateAttr(doc, "glEsVersion", str));
        return element;
    }

    private static XmlElement CreateNameElem(XmlDocument doc, string tag, string attrib)
    {
        XmlElement element = doc.CreateElement(tag);
        element.Attributes.Append(CreateAttr(doc, "name", attrib));
        return element;
    }

    private static void CreateSupportsTextureElem(XmlDocument doc, XmlElement manifestElem, AndroidBuildSubtarget subTarget)
    {
        switch (subTarget)
        {
            case AndroidBuildSubtarget.Generic:
            case AndroidBuildSubtarget.ETC:
                manifestElem.AppendChild(CreateNameElem(doc, "supports-gl-texture", "GL_OES_compressed_ETC1_RGB8_texture"));
                break;

            case AndroidBuildSubtarget.DXT:
                manifestElem.AppendChild(CreateNameElem(doc, "supports-gl-texture", "GL_EXT_texture_compression_dxt1"));
                manifestElem.AppendChild(CreateNameElem(doc, "supports-gl-texture", "GL_EXT_texture_compression_dxt5"));
                break;

            case AndroidBuildSubtarget.PVRTC:
                manifestElem.AppendChild(CreateNameElem(doc, "supports-gl-texture", "GL_IMG_texture_compression_pvrtc"));
                break;

            case AndroidBuildSubtarget.ATC:
                manifestElem.AppendChild(CreateNameElem(doc, "supports-gl-texture", "GL_AMD_compressed_ATC_texture"));
                manifestElem.AppendChild(CreateNameElem(doc, "supports-gl-texture", "GL_ATI_texture_compression_atitc"));
                break;

            default:
                UnityEngine.Debug.LogWarning("SubTarget not recognized : " + subTarget);
                break;
        }
    }

    private static string DeterminePackageName(bool devBuild, string playerPackage, string stagingArea, string assetsData, string manifestXml, float progress)
    {
        if (!PostprocessBuildPlayer.InstallPluginsByExtension("Assets/Plugins/Android", manifestXml, stagingArea, false))
        {
            FileUtil.CopyFileOrDirectory(Path.Combine(playerPackage, manifestXml), Path.Combine(stagingArea, manifestXml));
        }
        return PatchManifest(Path.Combine(stagingArea, manifestXml), assetsData, devBuild, progress);
    }

    private static bool doesReferenceNetworkClasses(AssemblyReferenceChecker checker)
    {
        return (((checker.HasReferenceToType("System.Net.Sockets") || checker.HasReferenceToType("UnityEngine.Network")) || checker.HasReferenceToType("UnityEngine.RPC")) || checker.HasReferenceToType("UnityEngine.WWW"));
    }

    internal static void EnsureLibraryIsAvailable(string playerPackage, string arch)
    {
        if (!File.Exists(playerPackage + "/libs/" + arch + "/libunity.so"))
        {
            ShowErrDlgAndThrow("Unable to package apk", "Missing unity library missing for the selected architecture '" + arch + "'!");
        }
    }

    private static string ExecuteSystemProcess(ProcessStartInfo psi, string[] progress_strings, float progress_value)
    {
        Program p = new Program(psi);
        p.Start();
        return WaitForProcessToFinish(p, progress_strings, progress_value);
    }

    private static string ExecuteSystemProcess(string command, string args, string workingdir, string[] progress_strings, float progress_value)
    {
        ProcessStartInfo psi = new ProcessStartInfo {
            FileName = command,
            Arguments = args,
            WorkingDirectory = workingdir,
            CreateNoWindow = true
        };
        return ExecuteSystemProcess(psi, progress_strings, progress_value);
    }

    private static int ExtractApiLevel(string platform)
    {
        char[] separator = new char[] { '-' };
        string[] source = platform.Split(separator);
        int num = platform_api_level;
        if (source.Count<string>() <= 1)
        {
            return platform_api_level;
        }
        try
        {
            num = Convert.ToInt32(source[1]);
        }
        catch (FormatException)
        {
            return platform_api_level;
        }
        return num;
    }

    private static string FindDeviceSerialNo(string path_to_adb, AndroidTargetDevice androidTargetDevice)
    {
        string serialno = string.Empty;
        using (Process process = new Process { StartInfo = { FileName = path_to_adb, Arguments = "start-server", CreateNoWindow = true, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true } })
        {
            process.Start();
            while (!process.WaitForExit(100))
            {
                progress.Show("Initializing ADB", "Starting up Android Debug Bridge...");
            }
        }
        progress.Advance();
        string[] strArray = new string[] { "Getting list of attached devices", "Trying locate a suitable Android device..." };
        string str2 = ExecuteSystemProcess(path_to_adb, "devices", string.Empty, strArray, progress.Advance());
        char[] separator = new char[] { '\n', '\r' };
        string[] strArray2 = str2.Split(separator);
        for (int i = 1; i < strArray2.Length; i++)
        {
            string str3 = strArray2[i];
            if (str3.Contains("device"))
            {
                serialno = str3.Substring(0, str3.IndexOf('\t'));
                break;
            }
        }
        if (serialno.Length == 0)
        {
            string message = string.Format("No Android devices found.{0}\n", (Application.platform != RuntimePlatform.WindowsEditor) ? string.Empty : " If you are sure that device is attached then it might be USB driver problem, for details please check Android SDK Setup section in Unity Manual.");
            ShowErrDlgAndThrow("Couldn't find Android device", message);
        }
        Dictionary<int, string> dictionary = AcquireDeviceInfo(path_to_adb, serialno);
        int num2 = Convert.ToInt32(dictionary["ro.build.version.sdk".GetHashCode()]);
        if (num2 < 5)
        {
            string str5 = "The connected device is not running Android OS 2.0 or later.";
            str5 = str5 + " Unity Android does not support earlier versions of the Android OS;" + " please upgrade your device to a later OS version.";
            Selection.activeObject = Unsupported.GetSerializedAssetInterfaceSingleton("PlayerSettings");
            ShowErrDlgAndThrow("Device software is not supported", str5);
        }
        else if ((num2 < 7) && PlayerSettings.Android.createWallpaper)
        {
            string str6 = "The connected device is not running Android OS 2.1 or later.";
            str6 = str6 + " Android Live Wallpapers are not suppored in Android OS prior to 2.1;" + " please upgrade your device to a later OS version.";
            Selection.activeObject = Unsupported.GetSerializedAssetInterfaceSingleton("PlayerSettings");
            ShowErrDlgAndThrow("Device software is not supported", str6);
        }
        string str7 = (androidTargetDevice != AndroidTargetDevice.ARMv7) ? "armeabi" : "armeabi-v7a";
        string str8 = dictionary["ro.product.cpu.abi".GetHashCode()];
        if ((androidTargetDevice == AndroidTargetDevice.ARMv7) && !str7.Equals(str8))
        {
            string str9 = "The connected device is not compatible with ARMv7a binaries.";
            Selection.activeObject = Unsupported.GetSerializedAssetInterfaceSingleton("PlayerSettings");
            ShowErrDlgAndThrow("Device hardware is not supported", str9);
        }
        int num3 = 0;
        try
        {
            num3 = Convert.ToInt32(dictionary["ro.opengles.version".GetHashCode()]);
        }
        catch (KeyNotFoundException)
        {
            num3 = -1;
        }
        int num4 = (PlayerSettings.targetGlesGraphics != TargetGlesGraphics.OpenGLES_2_0) ? 0x10000 : 0x20000;
        if ((num3 >= 0) && (num3 < num4))
        {
            string str10 = "The connected device is not compatible with OpenGLES version 2.0.";
            str10 = str10 + " Please select OpenGLES 1.x under Player Settings instead.";
            Selection.activeObject = Unsupported.GetSerializedAssetInterfaceSingleton("PlayerSettings");
            ShowErrDlgAndThrow("Device hardware is not supported", str10);
        }
        string str11 = dictionary["ro.product.manufacturer".GetHashCode()];
        string str12 = dictionary["ro.product.model".GetHashCode()];
        bool flag = dictionary["ro.secure".GetHashCode()].Equals("1");
        string action = string.Format("{0}{1} {2}", char.ToUpper(str11[0]), str11.Substring(1), str12);
        string label = string.Format("Android API-{0}", num2);
        Analytics.Event("Android Device", action, label, !flag ? 0 : 1);
        string str15 = string.Format("gles {0}.{1}", num3 >> 0x10, num3 & 0xffff);
        if (num3 < 0)
        {
            str15 = "gles 1.0";
        }
        Analytics.Event("Android Architecture", str8, str15, 1);
        string str16 = dictionary["ro.board.platform".GetHashCode()];
        string s = dictionary["MemTotal".GetHashCode()];
        try
        {
            int num5 = UpperboundPowerOf2(int.Parse(s)) / 0x400;
            s = string.Format("{0}MB", num5);
        }
        catch (System.Exception)
        {
            s = "Unknown";
        }
        Analytics.Event("Android Chipset", str16, s, 1);
        return serialno;
    }

    private static void FixConfigChangesAttr(XmlElement activityElem)
    {
        string attribute = activityElem.GetAttribute("android:configChanges");
        if (attribute == null)
        {
            attribute = string.Empty;
        }
        char[] separator = new char[] { '|' };
        HashSet<string> source = new HashSet<string>(attribute.Split(separator));
        source.Remove(string.Empty);
        source.Add("keyboardHidden");
        source.Add("orientation");
        attribute = string.Join("|", source.ToArray<string>());
        activityElem.SetAttribute("android:configChanges", attribute);
    }

    private static void FixOrientationAttr(XmlDocument doc, XmlElement activityElem)
    {
        UIOrientation defaultInterfaceOrientation = PlayerSettings.defaultInterfaceOrientation;
        XmlAttribute node = doc.CreateAttribute("android", "screenOrientation", "http://schemas.android.com/apk/res/android");
        int minSdkVersion = (int) PlayerSettings.Android.minSdkVersion;
        bool flag = PlayerSettings.allowedAutorotateToPortrait || PlayerSettings.allowedAutorotateToPortraitUpsideDown;
        bool flag2 = PlayerSettings.allowedAutorotateToLandscapeLeft || PlayerSettings.allowedAutorotateToLandscapeRight;
        switch (defaultInterfaceOrientation)
        {
            case UIOrientation.Portrait:
                node.Value = "portrait";
                break;

            case UIOrientation.PortraitUpsideDown:
                node.Value = "reversePortrait";
                break;

            case UIOrientation.LandscapeRight:
                node.Value = "reverseLandscape";
                break;

            case UIOrientation.LandscapeLeft:
                node.Value = "landscape";
                break;

            default:
                if (flag && flag2)
                {
                    node.Value = (minSdkVersion >= 9) ? "fullSensor" : "sensor";
                }
                else if (flag)
                {
                    node.Value = (minSdkVersion >= 9) ? "sensorPortrait" : "portrait";
                }
                else if (flag2)
                {
                    node.Value = (minSdkVersion >= 9) ? "sensorLandscape" : "landscape";
                }
                else
                {
                    node.Value = "unspecified";
                }
                break;
        }
        activityElem.Attributes.Append(node);
    }

    private static XmlElement GetActivityElement(XmlDocument doc, int i)
    {
        XmlNodeList elementsByTagName = doc.GetElementsByTagName("activity");
        if ((elementsByTagName.Count == 0) && (i == 0))
        {
            XmlElement newChild = doc.CreateElement("activity");
            newChild.Attributes.Append(CreateAttr(doc, "name", "com.unity3d.player.UnityPlayerActivity"));
            newChild.Attributes.Append(CreateAttr(doc, "label", "@string/app_name"));
            newChild.Attributes.Append(CreateAttr(doc, "configChanges", "keyboardHidden|orientation"));
            XmlElement element2 = doc.CreateElement("intent-filter");
            XmlElement element3 = doc.CreateElement("action");
            XmlElement element4 = doc.CreateElement("category");
            element3.Attributes.Append(CreateAttr(doc, "name", "android.intent.action.MAIN"));
            element4.Attributes.Append(CreateAttr(doc, "name", "android.intent.category.LAUNCHER"));
            element2.AppendChild(element3);
            element2.AppendChild(element4);
            newChild.AppendChild(element2);
            doc.DocumentElement.AppendChild(newChild);
            return newChild;
        }
        if (i < elementsByTagName.Count)
        {
            return (XmlElement) elementsByTagName[i];
        }
        return null;
    }

    private static string GetAndroidPlatform(string sdkRoot)
    {
        string str = string.Empty;
        string format = "{0}/platforms/{1}";
        string[] command = new string[] { "android", "list", "target", "-c" };
        string message = SDKTool(command, Directory.GetCurrentDirectory());
        char[] separator = new char[] { '\n', '\r' };
        foreach (string str4 in message.Split(separator))
        {
            string str5 = "android-";
            if (str4.StartsWith(str5))
            {
                int num2 = ExtractApiLevel(str4);
                if (num2 >= platform_api_level)
                {
                    string str6 = string.Format(format, sdkRoot, str4);
                    if (File.Exists(Path.Combine(str6, "android.jar")))
                    {
                        platform_api_level = num2;
                        str = str6;
                    }
                }
            }
        }
        if (str.Length == 0)
        {
            UnityEngine.Debug.LogError(message);
        }
        return str;
    }

    private static string GetAttrValueFromManifest(string manifest, string elemName, string attributeName)
    {
        XmlDocument document = new XmlDocument();
        XmlTextReader reader = new XmlTextReader(manifest);
        reader.Read();
        document.Load(reader);
        return document.GetElementsByTagName(elemName)[0].Attributes[attributeName].Value;
    }

    private static string GetMD5HashOfEOCD(string fileName)
    {
        long num = 0x10016L;
        FileStream inputStream = new FileStream(fileName, FileMode.Open);
        inputStream.Seek(inputStream.Length - Math.Min(inputStream.Length, num), SeekOrigin.Begin);
        byte[] buffer = new MD5CryptoServiceProvider().ComputeHash(inputStream);
        inputStream.Close();
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < buffer.Length; i++)
        {
            builder.Append(buffer[i].ToString("x2"));
        }
        return builder.ToString();
    }

    private static bool HasElementWithAttribute(XmlDocument doc, string element, string attrName, string attrValue)
    {
        IEnumerator enumerator = doc.GetElementsByTagName(element).GetEnumerator();
        try
        {
            while (enumerator.MoveNext())
            {
                XmlElement current = (XmlElement) enumerator.Current;
                if (current.HasAttribute(attrName) && (current.Attributes[attrName].Value == attrValue))
                {
                    return true;
                }
            }
        }
        finally
        {
            IDisposable disposable = enumerator as IDisposable;
            if (disposable == null)
            {
            }
            disposable.Dispose();
        }
        return false;
    }

    private static bool IsValidAndroidBundleIdentifier(string bundleIdentifier)
    {
        string extraValidChars = "_";
        bool flag = false;
        char[] separator = new char[] { '.' };
        foreach (string str2 in bundleIdentifier.Split(separator))
        {
            if (char.IsDigit(str2[0]) || (extraValidChars.IndexOf(str2[0]) != -1))
            {
                flag = true;
            }
        }
        return (!flag && PostProcessiPhonePlayer.IsValidBundleIdentifier(bundleIdentifier, extraValidChars));
    }

    private static int MinSdkVersion(AssemblyReferenceChecker checker)
    {
        return (int) PlayerSettings.Android.minSdkVersion;
    }

    private static bool NeedToAddGlesVersion(XmlDocument doc)
    {
        IEnumerator enumerator = doc.GetElementsByTagName("uses-feature").GetEnumerator();
        try
        {
            while (enumerator.MoveNext())
            {
                XmlElement current = (XmlElement) enumerator.Current;
                if (current.HasAttribute("android:glEsVersion"))
                {
                    return false;
                }
            }
        }
        finally
        {
            IDisposable disposable = enumerator as IDisposable;
            if (disposable == null)
            {
            }
            disposable.Dispose();
        }
        return true;
    }

    private static string PatchManifest(string manifest, string assetsData, bool development, float progress_value)
    {
        string bundleVersion = PlayerSettings.bundleVersion;
        int bundleVersionCode = PlayerSettings.Android.bundleVersionCode;
        XmlDocument doc = new XmlDocument();
        XmlTextReader reader = new XmlTextReader(manifest);
        reader.Read();
        doc.Load(reader);
        reader.Close();
        string bundleIdentifier = PlayerSettings.bundleIdentifier;
        if (IsValidAndroidBundleIdentifier(bundleIdentifier))
        {
            XmlAttribute newAttr = doc.CreateAttribute("package");
            newAttr.Value = bundleIdentifier;
            doc.DocumentElement.SetAttributeNode(newAttr);
        }
        else
        {
            bundleIdentifier = doc.DocumentElement.GetAttribute("package");
            if (string.IsNullOrEmpty(bundleIdentifier) || (bundleIdentifier == "com.unity3d.player"))
            {
                bundleIdentifier = PlayerSettings.bundleIdentifier;
            }
        }
        string str3 = PreferredInstallLocationAsString();
        doc.DocumentElement.SetAttribute("android:installLocation", str3);
        for (int i = 0; i < 4; i++)
        {
            XmlElement activityElement = GetActivityElement(doc, i);
            if (activityElement == null)
            {
                break;
            }
            FixOrientationAttr(doc, activityElement);
            FixConfigChangesAttr(activityElement);
        }
        XmlNodeList elementsByTagName = doc.GetElementsByTagName("application");
        elementsByTagName[0].Attributes.Append(doc.CreateAttribute("android", "debuggable", "http://schemas.android.com/apk/res/android"));
        if (development)
        {
            elementsByTagName[0].Attributes["android:debuggable"].Value = "true";
        }
        else
        {
            elementsByTagName[0].Attributes["android:debuggable"].Value = "false";
        }
        elementsByTagName = doc.GetElementsByTagName("manifest");
        elementsByTagName[0].Attributes.Append(doc.CreateAttribute("android", "versionName", "http://schemas.android.com/apk/res/android"));
        elementsByTagName[0].Attributes.Append(doc.CreateAttribute("android", "versionCode", "http://schemas.android.com/apk/res/android"));
        elementsByTagName[0].Attributes["android:versionName"].Value = bundleVersion;
        elementsByTagName[0].Attributes["android:versionCode"].Value = bundleVersionCode.ToString();
        XmlElement documentElement = doc.DocumentElement;
        if (NeedToAddGlesVersion(doc))
        {
            documentElement.AppendChild(CreateGlesVersionElem(doc));
        }
        if (EditorUserBuildSettings.androidBuildSubtarget != AndroidBuildSubtarget.Generic)
        {
            CreateSupportsTextureElem(doc, documentElement, EditorUserBuildSettings.androidBuildSubtarget);
        }
        AssemblyReferenceChecker checker = new AssemblyReferenceChecker();
        bool withMethods = true;
        bool ignoreSystemDlls = true;
        string path = assetsData + "/Data/Managed";
        checker.CollectReferences(path, withMethods, progress_value, ignoreSystemDlls);
        SetPermissionAttributes(doc, documentElement, development, checker);
        if (!PlayerSettings.advancedLicense)
        {
            string str5 = checker.WhoReferencesClass("System.Net.Sockets", true);
            if (str5 != null)
            {
                throw new SystemException("'System.Net.Sockets' are supported only with Unity Android Pro. Referenced from assembly '" + str5 + "'.");
            }
        }
        SetSdkElement(doc, checker);
        doc.Save(manifest);
        return bundleIdentifier;
    }

    private static void PatchStringRes(string stringsXml, string element, string attrib, string value)
    {
        XmlDocument document = new XmlDocument();
        document.Load(stringsXml);
        XmlNodeList elementsByTagName = document.GetElementsByTagName(element);
        bool flag = false;
        IEnumerator enumerator = elementsByTagName.GetEnumerator();
        try
        {
            while (enumerator.MoveNext())
            {
                XmlElement current = (XmlElement) enumerator.Current;
                if (current.Attributes["name"].Value == attrib)
                {
                    current.InnerText = value;
                    flag = true;
                }
            }
        }
        finally
        {
            IDisposable disposable = enumerator as IDisposable;
            if (disposable == null)
            {
            }
            disposable.Dispose();
        }
        if (!flag)
        {
            XmlElement newChild = document.CreateElement(element);
            XmlAttribute node = document.CreateAttribute(string.Empty, "name", string.Empty);
            node.Value = attrib;
            newChild.Attributes.Append(node);
            newChild.InnerText = value;
            document.DocumentElement.AppendChild(newChild);
        }
        document.Save(stringsXml);
    }

    internal static void PostProcess(BuildTarget target, string stagingAreaData, string stagingArea, string playerPackage, string installPath, string companyName, string productName, BuildOptions options)
    {
        try
        {
            PostProcessInternal(target, stagingAreaData, stagingArea, playerPackage, installPath, companyName, productName, options);
        }
        catch (ProcessAbortedException exception)
        {
            UnityEngine.Debug.LogWarning("Build process aborted (" + exception.Message + ")");
        }
    }

    internal static void PostProcessInternal(BuildTarget target, string stagingAreaData, string stagingArea, string playerPackage, string installPath, string companyName, string productName, BuildOptions options)
    {
        if (!ArePasswordsProvided())
        {
            ShowErrDlgAndThrow("Can not sign application", "Unable to sign application; please provide passwords!");
        }
        bool flag = (options & BuildOptions.AutoRunPlayer) != BuildOptions.None;
        float numSteps = !flag ? 10f : 17f;
        progress.Reset(numSteps);
        FileUtil.CopyFileOrDirectory(playerPackage + "/Data/unity default resources", stagingAreaData + "/unity default resources");
        string path = stagingArea + "/assets/bin";
        Directory.CreateDirectory(path);
        FileUtil.MoveFileOrDirectory(stagingAreaData, path + "/Data");
        string str2 = ResolveSdkRoot();
        if (string.IsNullOrEmpty(str2))
        {
            ShowErrDlgAndThrow("Android SDK not found!", "Could not locate Android SDK.");
        }
        PrepareToolPaths(str2);
        EditorPrefs.SetString("AndroidSdkRoot", str2);
        string manifestXml = "AndroidManifest.xml";
        bool devBuild = (options & BuildOptions.Development) != BuildOptions.None;
        string packageName = DeterminePackageName(devBuild, playerPackage, stagingArea, path, manifestXml, progress.Advance());
        ThrowIfInvalid(packageName);
        bool createWallpaper = PlayerSettings.Android.createWallpaper && Unsupported.IsDeveloperBuild();
        if (createWallpaper)
        {
            ConvertManifestToWallpaper(Path.Combine(stagingArea, manifestXml));
            string str5 = Path.Combine(stagingArea, "res/xml/wallpaper.xml");
            Directory.CreateDirectory(Path.GetDirectoryName(str5));
            string contents = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\t\t\t\t\t\t\t\t <wallpaper xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\t        \t\t\t\t\t android:thumbnail=\"@drawable/app_icon\"\n\t        \t\t\t\t\t android:author=\"@string/app_name\"\n\t        \t\t\t\t\t android:description=\"@string/app_name\" />";
            File.WriteAllText(str5, contents);
        }
        progress.Step("Creating staging area", "Setting up target contents directory...");
        if ((options & BuildOptions.InstallInBuildFolder) != BuildOptions.None)
        {
            FileUtil.CopyDirectoryRecursive(stagingArea + "/assets", playerPackage + "/assets", true);
        }
        else
        {
            SplitLargeFiles(stagingArea + "/assets/bin/Data", "*.assets", 0x100000);
            if (PlayerSettings.Android.useAPKExpansionFiles)
            {
                FileUtil.CopyDirectoryRecursive(stagingArea + "/assets", stagingArea + "/assets.apk");
                foreach (string str8 in Directory.GetFiles(path, "*", SearchOption.AllDirectories))
                {
                    if (Regex.IsMatch(str8.Substring(path.Length + 1).Replace(@"\", "/"), @"^(?:Data/mainData|Data/sharedassets0\.assets(?:\.res[GS]?)?(?:\.split\w+)?|Data/unity default resources|Data/PlayerConnectionConfigFile|Data/Managed/.+\.dll(?:\.mdb)?)$"))
                    {
                        FileUtil.DeleteFileOrDirectory(str8);
                    }
                }
                string[] strArray2 = new string[] { "Creating APK Expansion package", "Compiling all assets into one archive..." };
                string str9 = ExecuteSystemProcess(aapt_exe, "package -v -f -F obb.ap_ -A assets", stagingArea, strArray2, progress.Advance());
                if (!str9.Contains("Found 0 custom asset files") && (!str9.Contains("Done!") || !File.Exists(Path.Combine(stagingArea, "obb.ap_"))))
                {
                    UnityEngine.Debug.LogError("Android Asset Packaging Tool failed: " + str9);
                    ShowErrDlgAndThrow("AAPT Failed!", "Android Asset Packaging Tool failed. See the Console for details.");
                }
                Directory.Delete(stagingArea + "/assets", true);
                FileUtil.MoveFileOrDirectory(stagingArea + "/assets.apk", stagingArea + "/assets");
                foreach (string str10 in Directory.GetFiles(path, "*", SearchOption.AllDirectories))
                {
                    if (!Regex.IsMatch(str10.Substring(path.Length + 1).Replace(@"\", "/"), @"^(?:Data/mainData|Data/sharedassets0\.assets(?:\.res[GS]?)?(?:\.split\w+)?|Data/unity default resources|Data/PlayerConnectionConfigFile|Data/Managed/.+\.dll(?:\.mdb)?)$"))
                    {
                        FileUtil.DeleteFileOrDirectory(str10);
                    }
                }
            }
            string deviceSerial = string.Empty;
            if (flag)
            {
                deviceSerial = FindDeviceSerialNo(adb_exe, PlayerSettings.Android.targetDevice);
            }
            Directory.CreateDirectory(stagingArea + "/bin");
            bool flag4 = PostprocessBuildPlayer.InstallPluginsByExtension("Assets/Plugins/Android", ".jar", stagingArea + "/plugins", false);
            bool flag5 = PostprocessBuildPlayer.InstallPluginsByExtension("Assets/Plugins/Android/bin", ".jar", stagingArea + "/plugins", false);
            bool flag6 = PostprocessBuildPlayer.InstallPluginsByExtension("Assets/Plugins/Android/libs", ".jar", stagingArea + "/plugins", false);
            if (!((flag4 || flag5) || flag6))
            {
                FileUtil.CopyFileOrDirectory(playerPackage + "/bin/classes.dex", stagingArea + "/bin/classes.dex");
            }
            else
            {
                BuildDex(playerPackage, stagingArea);
            }
            FileUtil.CopyDirectoryRecursive(playerPackage + "/assets", stagingArea + "/assets", true);
            FileUtil.CopyDirectoryRecursive(playerPackage + "/res", stagingArea + "/res", true);
            if (Directory.Exists("Assets/Plugins/Android/res"))
            {
                FileUtil.CopyDirectoryRecursive("Assets/Plugins/Android/res", stagingArea + "/res", true, true);
            }
            if (Directory.Exists("Assets/Plugins/Android/assets"))
            {
                FileUtil.CopyDirectoryRecursive("Assets/Plugins/Android/assets", stagingArea + "/assets", true, true);
            }
            string stringsXml = Path.Combine(stagingArea, "res/values/strings.xml");
            productName = productName.Replace("'", @"\'");
            productName = productName.Replace("\"", "\\\"");
            PatchStringRes(stringsXml, "string", "app_name", productName);
            string str13 = (PlayerSettings.targetGlesGraphics != TargetGlesGraphics.OpenGLES_2_0) ? "1" : "2";
            bool flag8 = PlayerSettings.use32BitDisplayBuffer;
            bool flag9 = PlayerSettings.Android.use24BitDepthBuffer;
            int antiAliasing = QualitySettings.antiAliasing;
            int num5 = !PlayerSettings.advancedLicense ? 0 : ((int) PlayerSettings.Android.splashScreenScale);
            bool statusBarHidden = PlayerSettings.statusBarHidden;
            bool useAPKExpansionFiles = PlayerSettings.Android.useAPKExpansionFiles;
            bool debuggable = (options & BuildOptions.Development) != BuildOptions.None;
            string str14 = Path.Combine(stagingArea, "assets/bin/Data/settings.xml");
            PatchStringRes(str14, "integer", "gles_mode", str13);
            PatchStringRes(str14, "integer", "splash_mode", num5.ToString());
            PatchStringRes(str14, "bool", "hide_status_bar", statusBarHidden.ToString());
            PatchStringRes(str14, "bool", "32bit_display", flag8.ToString());
            PatchStringRes(str14, "bool", "24bit_depth", flag9.ToString());
            PatchStringRes(str14, "integer", "default_aa", antiAliasing.ToString());
            PatchStringRes(str14, "bool", "useObb", useAPKExpansionFiles.ToString());
            if (debuggable)
            {
                PatchStringRes(str14, "bool", "development_player", debuggable.ToString());
            }
            ReplaceIconResources(stagingArea);
            Directory.CreateDirectory(stagingArea + "/gen");
            object[] args = new object[] { "gen", manifestXml, "res", android_jar, "bin/resources.ap_" };
            string str15 = string.Format("package -v -f -m -J {0} -M {1} -S \"{2}\" -I \"{3}\" -F {4}", args);
            string[] strArray4 = new string[] { "Rebuilding resources", "Updating resources with player settings..." };
            string str16 = ExecuteSystemProcess(aapt_exe, str15, stagingArea, strArray4, progress.Advance());
            if (!str16.Contains("Done!") || !File.Exists(Path.Combine(stagingArea, "bin/resources.ap_")))
            {
                UnityEngine.Debug.LogError("Failed to re-package resources with the following parameters:\n" + str15 + "\n" + str16);
                ShowErrDlgAndThrow("Resource re-package failed!", "Failed to re-package resources. See the Console for details.");
            }
            if (PlayerSettings.Android.targetDevice == AndroidTargetDevice.ARMv7)
            {
                CopyNativeLibs(target, playerPackage, stagingArea, "armeabi-v7a", "armeabi");
            }
            if (!debuggable)
            {
                if (File.Exists(stagingArea + "/libs/armeabi/libmono_soft.so"))
                {
                    Directory.CreateDirectory(stagingArea + "/assets/libs/armeabi-soft");
                    File.Move(stagingArea + "/libs/armeabi/libmono_soft.so", stagingArea + "/assets/libs/armeabi-soft/libmono.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi/libmono.so"))
                {
                    Directory.CreateDirectory(stagingArea + "/assets/libs/armeabi-vfp");
                    File.Move(stagingArea + "/libs/armeabi/libmono.so", stagingArea + "/assets/libs/armeabi-vfp/libmono.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi-v7a/libmono.so"))
                {
                    Directory.CreateDirectory(stagingArea + "/assets/libs/armeabi-v7a");
                    File.Move(stagingArea + "/libs/armeabi-v7a/libmono.so", stagingArea + "/assets/libs/armeabi-v7a/libmono.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi/libmono_soft_proxy.so"))
                {
                    File.Move(stagingArea + "/libs/armeabi/libmono_soft_proxy.so", stagingArea + "/libs/armeabi/libmono.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi/libmono_proxy.so"))
                {
                    File.Move(stagingArea + "/libs/armeabi/libmono_proxy.so", stagingArea + "/libs/armeabi/libmono.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi-v7a/libmono_proxy.so"))
                {
                    File.Move(stagingArea + "/libs/armeabi-v7a/libmono_proxy.so", stagingArea + "/libs/armeabi-v7a/libmono.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi/libunity_soft.so"))
                {
                    Directory.CreateDirectory(stagingArea + "/assets/libs/armeabi-soft");
                    File.Move(stagingArea + "/libs/armeabi/libunity_soft.so", stagingArea + "/assets/libs/armeabi-soft/libunity.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi/libunity.so"))
                {
                    Directory.CreateDirectory(stagingArea + "/assets/libs/armeabi-vfp");
                    File.Move(stagingArea + "/libs/armeabi/libunity.so", stagingArea + "/assets/libs/armeabi-vfp/libunity.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi-v7a/libunity.so"))
                {
                    Directory.CreateDirectory(stagingArea + "/assets/libs/armeabi-v7a");
                    File.Move(stagingArea + "/libs/armeabi-v7a/libunity.so", stagingArea + "/assets/libs/armeabi-v7a/libunity.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi/libunity_soft_proxy.so"))
                {
                    File.Move(stagingArea + "/libs/armeabi/libunity_soft_proxy.so", stagingArea + "/libs/armeabi/libunity.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi/libunity_proxy.so"))
                {
                    File.Move(stagingArea + "/libs/armeabi/libunity_proxy.so", stagingArea + "/libs/armeabi/libunity.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi-v7a/libunity_proxy.so"))
                {
                    File.Move(stagingArea + "/libs/armeabi-v7a/libunity_proxy.so", stagingArea + "/libs/armeabi-v7a/libunity.so");
                }
            }
            else
            {
                if (File.Exists(stagingArea + "/libs/armeabi/libmono_soft.so"))
                {
                    File.Move(stagingArea + "/libs/armeabi/libmono_soft.so", stagingArea + "/libs/armeabi/libmono.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi/libunity_soft.so"))
                {
                    File.Move(stagingArea + "/libs/armeabi/libunity_soft.so", stagingArea + "/libs/armeabi/libunity.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi/libmono_soft_proxy.so"))
                {
                    FileUtil.DeleteFileOrDirectory(stagingArea + "/libs/armeabi/libmono_soft_proxy.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi/libunity_soft_proxy.so"))
                {
                    FileUtil.DeleteFileOrDirectory(stagingArea + "/libs/armeabi/libunity_soft_proxy.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi/libmono_proxy.so"))
                {
                    FileUtil.DeleteFileOrDirectory(stagingArea + "/libs/armeabi/libmono_proxy.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi-v7a/libmono_proxy.so"))
                {
                    FileUtil.DeleteFileOrDirectory(stagingArea + "/libs/armeabi-v7a/libmono_proxy.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi/libunity_proxy.so"))
                {
                    FileUtil.DeleteFileOrDirectory(stagingArea + "/libs/armeabi/libunity_proxy.so");
                }
                if (File.Exists(stagingArea + "/libs/armeabi-v7a/libunity_proxy.so"))
                {
                    FileUtil.DeleteFileOrDirectory(stagingArea + "/libs/armeabi-v7a/libunity_proxy.so");
                }
            }
            if (File.Exists(stagingArea + "/libs/x86/libmono_proxy.so"))
            {
                FileUtil.DeleteFileOrDirectory(stagingArea + "/libs/x86/libmono_proxy.so");
            }
            if (File.Exists(stagingArea + "/libs/x86/libunity_proxy.so"))
            {
                FileUtil.DeleteFileOrDirectory(stagingArea + "/libs/x86/libunity_proxy.so");
            }
            string str17 = path + "/Data";
            string str18 = stagingArea + "/raw/bin/Data";
            string strB = ".resS";
            foreach (string str20 in Directory.GetFileSystemEntries(str17))
            {
                if (string.Compare(Path.GetExtension(str20), strB, true) == 0)
                {
                    if (!Directory.Exists(str18))
                    {
                        Directory.CreateDirectory(str18);
                    }
                    string destFileName = Path.Combine(str18, Path.GetFileName(str20));
                    File.Move(str20, destFileName);
                }
            }
            if (Directory.Exists("Assets/StreamingAssets"))
            {
                FileUtil.CopyDirectoryRecursiveForPostprocess("Assets/StreamingAssets", stagingArea + "/raw", true);
            }
            if (Directory.Exists(stagingArea + "/raw"))
            {
                string[] strArray7 = new string[] { "Creating streaming package", "Compiling all streaming assets into one archive..." };
                string str22 = ExecuteSystemProcess(aapt_exe, "package -v -f -F raw.ap_ -A raw -0 \"\"", stagingArea, strArray7, progress.Advance());
                if (!str22.Contains("Found 0 custom asset files") && (!str22.Contains("Done!") || !File.Exists(Path.Combine(stagingArea, "raw.ap_"))))
                {
                    UnityEngine.Debug.LogError("Android Asset Packaging Tool failed: " + str22);
                    ShowErrDlgAndThrow("AAPT Failed!", "Android Asset Packaging Tool failed. See the Console for details.");
                }
            }
            if (useAPKExpansionFiles)
            {
                BuildObb(stagingArea);
            }
            string[] strArray8 = new string[] { "Creating asset package", "Compiling all assets into one archive..." };
            string str23 = ExecuteSystemProcess(aapt_exe, "package -v -f -F assets.ap_ -A assets", stagingArea, strArray8, progress.Advance());
            if (!str23.Contains("Done!") || !File.Exists(Path.Combine(stagingArea, "assets.ap_")))
            {
                UnityEngine.Debug.LogError("Android Asset Packaging Tool failed: " + str23);
                ShowErrDlgAndThrow("AAPT Failed!", "Android Asset Packaging Tool failed. See the Console for details.");
            }
            if ((options & BuildOptions.AcceptExternalModificationsToPlayer) != BuildOptions.None)
            {
                new EclipseProject(playerPackage, stagingArea, installPath, packageName, productName, platform_api_level).Create();
            }
            else
            {
                bool flag13 = PlayerSettings.Android.keyaliasName.Length != 0;
                BuildApk(stagingArea, flag13, debuggable);
                AlignPackage(stagingArea);
                if (flag)
                {
                    UploadAndStartPlayer(adb_exe, Path.Combine(stagingArea, manifestXml), stagingArea, deviceSerial, packageName, createWallpaper, debuggable || Unsupported.IsDeveloperBuild(), false);
                }
                progress.Step("Copying to output folder", "Moving final Android package...");
                FileUtil.DeleteFileOrDirectory(installPath);
                if (File.Exists(installPath))
                {
                    ShowErrDlgAndThrow("Unable to delete old apk!", string.Format("Target apk could not be overwritten: {0}", installPath));
                }
                FileUtil.MoveFileOrDirectory(Path.Combine(stagingArea, "Package.apk"), installPath);
                if (!File.Exists(installPath))
                {
                    ShowErrDlgAndThrow("Unable to create new apk!", string.Format("Unable to move file '{0}' -> '{1}", Path.Combine(stagingArea, "Package.apk"), installPath));
                }
                if (useAPKExpansionFiles && File.Exists(Path.Combine(stagingArea, "main.obb")))
                {
                    string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(installPath);
                    string str25 = Path.Combine(Path.GetDirectoryName(installPath), string.Format("{0}.main.obb", fileNameWithoutExtension));
                    FileUtil.DeleteFileOrDirectory(str25);
                    FileUtil.MoveFileOrDirectory(Path.Combine(stagingArea, "main.obb"), str25);
                }
            }
        }
    }

    private static string PreferredInstallLocationAsString()
    {
        switch (PlayerSettings.Android.preferredInstallLocation)
        {
            case AndroidPreferredInstallLocation.Auto:
                return "auto";

            case AndroidPreferredInstallLocation.PreferExternal:
                return "preferExternal";

            case AndroidPreferredInstallLocation.ForceInternal:
                return "internalOnly";
        }
        return "preferExternal";
    }

    internal static void PrepareToolPaths(string sdk_root_dir)
    {
        platform_api_level = 14;
        string str = Path.Combine(sdk_root_dir, "tools");
        sdk_tools = new AndroidSDKTools(sdk_root_dir);
        aapt_exe = "aapt";
        adb_exe = "adb";
        zipalign_exe = "zipalign";
        java_exe = "java";
        android_jar = "android.jar";
        if (Application.platform == RuntimePlatform.WindowsEditor)
        {
            aapt_exe = aapt_exe + ".exe";
            adb_exe = adb_exe + ".exe";
            zipalign_exe = zipalign_exe + ".exe";
            java_exe = java_exe + ".exe";
        }
        string androidPlatform = GetAndroidPlatform(sdk_root_dir);
        string str3 = androidPlatform;
        string str4 = str;
        string str5 = Path.Combine(sdk_root_dir, "platform-tools");
        if (File.Exists(Path.Combine(str5, aapt_exe)))
        {
            str4 = androidPlatform = str5;
        }
        if (str3.Length == 0)
        {
            string message = "Android SDK does not include any platforms! Did you run Android SDK setup to install the platform(s)?\nMinimum platform required for build is Android 4.0 (API level 14)\n";
            ShowErrDlgAndThrow("No platforms found", message);
        }
        aapt_exe = Path.Combine(androidPlatform, aapt_exe);
        adb_exe = Path.Combine(str4, adb_exe);
        zipalign_exe = Path.Combine(str, zipalign_exe);
        java_exe = Path.Combine(AndroidSDKTools.LocateJDKbin(), java_exe);
        android_jar = Path.Combine(str3, android_jar);
    }

    private static void ReplaceIconResources(string stagingArea)
    {
        string[] array = new string[] { "res.drawable-ldpi.app_icon.png", "res/drawable-ldpi/app_icon.png", "res.drawable-mdpi.app_icon.png", "res/drawable/app_icon.png", "res.drawable-hdpi.app_icon.png", "res/drawable-hdpi/app_icon.png", "res.drawable-xhdpi.app_icon.png", "res/drawable-xhdpi/app_icon.png", "app_splash.png", "assets/bin/Data/splash.png" };
        if (!PlayerSettings.advancedLicense)
        {
            Array.Resize<string>(ref array, array.Length - 2);
        }
        for (int i = 0; i < array.Length; i += 2)
        {
            string path = Path.Combine(stagingArea, array[i]);
            string str2 = Path.Combine(stagingArea, array[i + 1]);
            if (File.Exists(path))
            {
                FileUtil.DeleteFileOrDirectory(str2);
                Directory.CreateDirectory(Path.GetDirectoryName(str2));
                FileUtil.MoveFileOrDirectory(path, str2);
            }
        }
    }

    private static string ResolveSdkRoot()
    {
        string title = "Detecting Android SDK";
        string message = "Trying to locate the Android SDK installation folder...";
        progress.Step(title, message);
        string path = EditorPrefs.GetString("AndroidSdkRoot");
        EditorPrefs.SetString("AndroidSdkRoot", string.Empty);
        if (AndroidSdkRoot.IsSdkDir(path))
        {
            return path;
        }
        return AndroidSdkRoot.Browse(path);
    }

    private static string SDKTool(string[] command, string workingdir)
    {
        return SDKTool(command, workingdir, null, 0f);
    }

    private static string SDKTool(string[] command, string workingdir, string[] progress_strings, float progress_value)
    {
        <SDKTool>c__AnonStorey30 storey = new <SDKTool>c__AnonStorey30 {
            progress_strings = progress_strings,
            progress_value = progress_value
        };
        return sdk_tools.RunCommand(command, workingdir, new AndroidSDKTools.WaitingForProcessToExit(storey.<>m__49));
    }

    private static void SetPermissionAttributes(XmlDocument doc, XmlElement manifestElem, bool development, AssemblyReferenceChecker checker)
    {
        bool flag = false;
        bool flag2 = true;
        bool forceInternetPermission = PlayerSettings.Android.forceInternetPermission;
        bool forceSDCardPermission = PlayerSettings.Android.forceSDCardPermission;
        if (!forceInternetPermission)
        {
            flag2 = doesReferenceNetworkClasses(checker);
        }
        if (checker.HasReferenceToMethod("UnityEngine.SystemInfo::get_deviceUniqueIdentifier") || checker.HasReferenceToMethod("UnityEngine.iPhoneSettings::get_uniqueIdentifier"))
        {
            flag = flag2 = true;
        }
        bool useAPKExpansionFiles = PlayerSettings.Android.useAPKExpansionFiles;
        bool flag6 = checker.HasReferenceToMethod("UnityEngine.iPhoneSettings::get_internetReachability") || checker.HasReferenceToMethod("UnityEngine.Application::get_internetReachability");
        flag6 |= useAPKExpansionFiles;
        flag2 |= useAPKExpansionFiles;
        forceSDCardPermission |= useAPKExpansionFiles;
        if (flag2 || development)
        {
            AppendPermissionWithCheck(doc, manifestElem, "android.permission.INTERNET");
        }
        if (checker.HasReferenceToMethod("UnityEngine.Handheld::Vibrate"))
        {
            AppendPermissionWithCheck(doc, manifestElem, "android.permission.VIBRATE");
        }
        if (flag)
        {
            AppendPermissionWithCheck(doc, manifestElem, "android.permission.READ_PHONE_STATE");
        }
        if (flag6)
        {
            AppendPermissionWithCheck(doc, manifestElem, "android.permission.ACCESS_NETWORK_STATE");
        }
        if (useAPKExpansionFiles)
        {
            AppendPermissionWithCheck(doc, manifestElem, "android.permission.ACCESS_WIFI_STATE");
        }
        if (useAPKExpansionFiles)
        {
            AppendPermissionWithCheck(doc, manifestElem, "com.android.vending.CHECK_LICENSE");
        }
        if (((checker.HasReferenceToMethod("UnityEngine.Input::get_location") || checker.HasReferenceToMethod("UnityEngine.iPhoneInput::get_lastLocation")) || (checker.HasReferenceToMethod("UnityEngine.iPhoneSettings::get_locationServiceStatus") || checker.HasReferenceToMethod("UnityEngine.iPhoneSettings::get_locationServiceEnabledByUser"))) || (checker.HasReferenceToMethod("UnityEngine.iPhoneSettings::StartLocationServiceUpdates") || checker.HasReferenceToMethod("UnityEngine.iPhoneSettings::StopLocationServiceUpdates")))
        {
            AppendPermissionWithCheck(doc, manifestElem, "android.permission.ACCESS_FINE_LOCATION");
            AddUsesFeatureTag(doc, "android.hardware.location.gps", false);
        }
        if (checker.HasReferenceToType("UnityEngine.WebCamTexture"))
        {
            AppendPermissionWithCheck(doc, manifestElem, "android.permission.CAMERA");
            AddUsesFeatureTag(doc, "android.hardware.camera", false);
            AddUsesFeatureTag(doc, "android.hardware.camera.autofocus", false);
            AddUsesFeatureTag(doc, "android.hardware.camera.front", false);
        }
        if (checker.HasReferenceToType("UnityEngine.Microphone"))
        {
            AppendPermissionWithCheck(doc, manifestElem, "android.permission.RECORD_AUDIO");
            AddUsesFeatureTag(doc, "android.hardware.microphone", true);
        }
        if (forceSDCardPermission || development)
        {
            AppendPermissionWithCheck(doc, manifestElem, "android.permission.WRITE_EXTERNAL_STORAGE");
        }
        if ((checker.HasReferenceToMethod("UnityEngine.Input::get_acceleration") || checker.HasReferenceToMethod("UnityEngine.Input::GetAccelerationEvent")) || (checker.HasReferenceToMethod("UnityEngine.Input::get_accelerationEvents") || checker.HasReferenceToMethod("UnityEngine.Input::get_accelerationEventCount")))
        {
            AddUsesFeatureTag(doc, "android.hardware.sensor.accelerometer", true);
        }
        if (((checker.HasReferenceToMethod("UnityEngine.Input::get_touches") || checker.HasReferenceToMethod("UnityEngine.Input::GetTouch")) || (checker.HasReferenceToMethod("UnityEngine.Input::get_touchCount") || checker.HasReferenceToMethod("UnityEngine.Input::get_multiTouchEnabled"))) || (((checker.HasReferenceToMethod("UnityEngine.Input::set_multiTouchEnabled") || checker.HasReferenceToMethod("UnityEngine.iPhoneInput::get_touches")) || (checker.HasReferenceToMethod("UnityEngine.iPhoneInput::GetTouch") || checker.HasReferenceToMethod("UnityEngine.iPhoneInput::get_touchCount"))) || (checker.HasReferenceToMethod("UnityEngine.iPhoneInput::get_multiTouchEnabled") || checker.HasReferenceToMethod("UnityEngine.iPhoneInput::set_multiTouchEnabled"))))
        {
            AddUsesFeatureTag(doc, "android.hardware.touchscreen", true);
            AddUsesFeatureTag(doc, "android.hardware.touchscreen.multitouch", false);
            AddUsesFeatureTag(doc, "android.hardware.touchscreen.multitouch.distinct", false);
        }
        if ((checker.HasReferenceToMethod("UnityEngine.iPhoneInput::get_acceleration") || checker.HasReferenceToMethod("UnityEngine.iPhoneInput::GetAccelerationEvent")) || (checker.HasReferenceToMethod("UnityEngine.iPhoneInput::get_accelerationEvents") || checker.HasReferenceToMethod("UnityEngine.iPhoneInput::get_accelerationEventCount")))
        {
            AddUsesFeatureTag(doc, "android.hardware.sensor.accelerometer", true);
        }
        if (checker.HasReferenceToMethod("UnityEngine.iPhoneUtils::Vibrate"))
        {
            AppendPermissionWithCheck(doc, manifestElem, "android.permission.VIBRATE");
        }
        if ((checker.HasReferenceToMethod("UnityEngine.Screen::set_sleepTimeout") || checker.HasReferenceToMethod("UnityEngine.Handheld::PlayFullScreenMovie")) || checker.HasReferenceToMethod("UnityEngine.iPhoneSettings::set_screenCanDarken"))
        {
            AppendPermissionWithCheck(doc, manifestElem, "android.permission.WAKE_LOCK");
        }
    }

    private static void SetSdkElement(XmlDocument doc, AssemblyReferenceChecker checker)
    {
        XmlNodeList elementsByTagName = doc.GetElementsByTagName("uses-sdk");
        XmlElement newChild = null;
        bool flag = true;
        bool flag2 = true;
        if (elementsByTagName.Count == 0)
        {
            newChild = doc.CreateElement("uses-sdk");
            doc.DocumentElement.AppendChild(newChild);
        }
        else
        {
            newChild = (XmlElement) elementsByTagName[0];
            for (int i = 0; i < elementsByTagName.Count; i++)
            {
                if (((XmlElement) elementsByTagName[i]).HasAttribute("android:minSdkVersion"))
                {
                    flag = false;
                }
                if (((XmlElement) elementsByTagName[i]).HasAttribute("android:targetSdkVersion"))
                {
                    flag2 = false;
                }
            }
        }
        int num2 = MinSdkVersion(checker);
        if (flag)
        {
            XmlAttribute newAttr = doc.CreateAttribute("android", "minSdkVersion", "http://schemas.android.com/apk/res/android");
            newAttr.Value = num2.ToString();
            newChild.SetAttributeNode(newAttr);
        }
        int num3 = (num2 <= platform_api_level) ? platform_api_level : num2;
        if (flag2)
        {
            XmlAttribute attribute2 = doc.CreateAttribute("android", "targetSdkVersion", "http://schemas.android.com/apk/res/android");
            attribute2.Value = num3.ToString();
            newChild.SetAttributeNode(attribute2);
        }
    }

    private static void ShowErrDlgAndThrow(string title, string message)
    {
        EditorUtility.DisplayDialog(title, message, "Ok");
        throw new UnityException(title + "\n" + message);
    }

    private static void SplitLargeFiles(string path, string extension, int threshold)
    {
        byte[] array = new byte[0x4000];
        foreach (string str in Directory.GetFiles(path, extension, SearchOption.AllDirectories))
        {
            FileInfo info = new FileInfo(str);
            if (info.Length >= threshold)
            {
                FileStream stream = File.Open(info.FullName, FileMode.Open);
                long length = info.Length;
                for (long i = 0L; length > 0L; i += 1L)
                {
                    long num5 = Math.Min(length, (long) threshold);
                    FileStream stream2 = File.Open(Path.Combine(info.DirectoryName, info.Name + ".split" + i), FileMode.OpenOrCreate);
                    for (long j = num5; j > 0L; j -= 0x4000L)
                    {
                        int count = (int) Math.Min(j, 0x4000L);
                        stream.Read(array, 0, count);
                        stream2.Write(array, 0, count);
                    }
                    stream2.Close();
                    length -= threshold;
                }
                stream.Close();
                File.Delete(str);
            }
        }
    }

    private static string StringConcat(IEnumerable<string> strings)
    {
        StringBuilder builder = new StringBuilder(string.Empty);
        IEnumerator<string> enumerator = strings.GetEnumerator();
        try
        {
            while (enumerator.MoveNext())
            {
                builder.Append(enumerator.Current + Environment.NewLine);
            }
        }
        finally
        {
            if (enumerator == null)
            {
            }
            enumerator.Dispose();
        }
        return builder.ToString();
    }

    private static void ThrowIfInvalid(string packageName)
    {
        if (!IsValidAndroidBundleIdentifier(packageName))
        {
            string message = "Please set the Bundle Identifier in the Player Settings.";
            message = (message + " The value must follow the convention 'com.YourCompanyName.YourProductName'") + " and can contain alphanumeric characters and underscore." + "\nEach segment must not start with a numeric character or underscore.";
            Selection.activeObject = Unsupported.GetSerializedAssetInterfaceSingleton("PlayerSettings");
            ShowErrDlgAndThrow("Bundle Identifier has not been set up correctly", message);
        }
    }

    private static void UploadAndStartPlayer(string path_to_adb, string manifestName, string stagingArea, string deviceSerial, string packageName, bool createWallpaper, bool devPlayer, bool retryUpload)
    {
        string str = string.Format("-s {0} ", deviceSerial);
        string[] strArray = new string[] { "Installing new player", "Pushing new content to device " + deviceSerial };
        string str2 = ExecuteSystemProcess(path_to_adb, str + "install -r Package.apk", stagingArea, strArray, progress.Advance());
        if (!retryUpload && (str2.Contains("[INSTALL_FAILED_UPDATE_INCOMPATIBLE]") || str2.Contains("[INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES]")))
        {
            UnityEngine.Debug.LogWarning("Application update incompatible (signed with different keys?); removing previous installation (PlayerPrefs will be lost)...\n");
            string[] strArray2 = new string[] { "Uninstalling old player", "Removing " + packageName + " from device " + deviceSerial };
            string args = string.Format("{0}shell pm uninstall {1}", str, packageName);
            ExecuteSystemProcess(path_to_adb, args, string.Empty, strArray2, progress.LastValue());
            UploadAndStartPlayer(path_to_adb, manifestName, stagingArea, deviceSerial, packageName, createWallpaper, devPlayer, true);
        }
        else
        {
            if (((str2.Contains("protocol failure") || str2.Contains("No space left on device")) || (str2.Contains("[INSTALL_FAILED_INSUFFICIENT_STORAGE]") || str2.Contains("[INSTALL_FAILED_UPDATE_INCOMPATIBLE]"))) || ((str2.Contains("[INSTALL_FAILED_MEDIA_UNAVAILABLE]") || str2.Contains("[INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES]")) || str2.Contains("Failure [")))
            {
                UnityEngine.Debug.LogError("Installation failed with the following output:\n" + str2);
                ShowErrDlgAndThrow("Unable to install APK!", "Installation failed. See the Console for details.");
            }
            if (!createWallpaper)
            {
                string[] strArray3 = new string[] { "Setting up environment", "Setting device property CheckJNI to " + devPlayer };
                string str4 = str + string.Format("shell setprop debug.checkjni {0}", !devPlayer ? "0" : "1");
                ExecuteSystemProcess(path_to_adb, str4, string.Empty, strArray3, progress.LastValue());
                if (PlayerSettings.Android.useAPKExpansionFiles && File.Exists(Path.Combine(stagingArea, "main.obb")))
                {
                    int bundleVersionCode = PlayerSettings.Android.bundleVersionCode;
                    int hashCode = "ro.build.version.sdk".GetHashCode();
                    int num3 = Convert.ToInt32(AcquireDeviceInfo(path_to_adb, deviceSerial)[hashCode]);
                    string str5 = "/sdcard/Android";
                    string str6 = "/mnt/shell/emulated";
                    string str7 = (num3 >= 0x11) ? str6 : str5;
                    string str8 = "obb";
                    string str9 = string.Format("main.{0}.{1}.obb", bundleVersionCode.ToString(), packageName);
                    object[] objArray1 = new object[] { str7, str8, packageName, str9 };
                    string str10 = string.Format("{0}/{1}/{2}/{3}", objArray1);
                    string[] strArray4 = new string[] { "Pushing expansion (.obb) file", "Copying APK Expansion file (main.obb)" };
                    string str11 = str + string.Format("push main.obb {0}", str10);
                    ExecuteSystemProcess(path_to_adb, str11, stagingArea, strArray4, progress.LastValue());
                }
                string[] strArray5 = new string[] { "Launching new player", "Attempting to start Unity Player on device " + deviceSerial };
                string str12 = GetAttrValueFromManifest(manifestName, "activity", "android:name");
                string[] textArray6 = new string[] { str, "shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000 -n ", packageName, "/", str12 };
                string str13 = string.Concat(textArray6);
                ExecuteSystemProcess(path_to_adb, str13, string.Empty, strArray5, progress.Advance());
            }
        }
    }

    private static int UpperboundPowerOf2(int i)
    {
        i--;
        i |= i >> 1;
        i |= i >> 2;
        i |= i >> 4;
        i |= i >> 8;
        i |= i >> 0x10;
        return (i + 1);
    }

    private static string WaitForProcessToFinish(Program p, string[] progress_strings, float progress_value)
    {
        do
        {
            if ((progress_strings != null) && EditorUtility.DisplayCancelableProgressBar(progress_strings[0], progress_strings[1], progress_value))
            {
                p.Dispose();
                throw new ProcessAbortedException(progress_strings[0]);
            }
        }
        while (!p.WaitForExit(100));
        string str = StringConcat(p.GetStandardOutput()) + StringConcat(p.GetErrorOutput());
        p.Dispose();
        return str;
    }

    [CompilerGenerated]
    private sealed class <SDKTool>c__AnonStorey30
    {
        internal string[] progress_strings;
        internal float progress_value;

        internal void <>m__49()
        {
            if ((this.progress_strings != null) && EditorUtility.DisplayCancelableProgressBar(this.progress_strings[0], this.progress_strings[1], this.progress_value))
            {
                throw new ProcessAbortedException(this.progress_strings[0]);
            }
        }
    }
}

